如果我有一个长时间运行的system
命令apt-cache search
,有没有办法在命令行上将SIGINT
发送的转发转发^C
到父Perl进程,以便获得所有子进程.
此示例没有所需的行为.信号被发送到子进程.
#!/usr/bin/env perl use strict; use warnings FATAL => 'all'; use autodie; # long running command on ubuntu, produces a ton of output. # replace with your favorite long running command system("apt-cache search hi"); print("Perl did not catch SIGINT even with autodie\n");
我试图捕捉将由创建的子进程的PID方式摸索system("apt-cache search hi &")
,但找不到任何,所以我尝试fork
荷兰国际集团和exec
荷兰国际集团的过程中,写信号处理程序.这不起作用,因为apt-cache
它本身通过clone
系统调用启动了一些进程.手动滚动一些逻辑来遍历流程树的一部分并清理它
#!/usr/bin/env perl use strict; use warnings FATAL => 'all'; use autodie; my $cpid; $SIG{INT} = sub { kill 'KILL', $cpid; exit; }; # long running command on ubuntu, produces a ton of output. # replace with your favorite long running command $cpid = fork; if ($cpid == 0) { exec 'apt-cache', 'search', 'hi'; } print "Perl did not catch SIGINT even with autodie\n";
我想基本上我想要的是一种确定子进程是否system
由于信号而退出的方式,因为SIGINT
我可以让Perl脚本自行清理,或者以一种方式遍历子进程并以这种方式收获它们过程管理的奇怪边缘情况得到了干净和便携的处理.
让孩子成为进程组的负责人,然后将信号发送给整个进程组.
#!/usr/bin/perl use strict; use warnings; use autodie; use POSIX qw( setpgid ); my $child_pid; $SIG{INT} = sub { kill INT => -$child_pid if $child_pid; exit(0x80 | 2); # 2 = SIGINT }; my $child_pid = fork(); if (!$child_pid) { setpgid($$); exec 'apt-cache', 'search', 'hi'; } WAIT: { no autodie; waitpid($child_pid, 0); redo WAIT if $? == -1 and $!{EINTR}; die $! if $? == -1; } exit( ( $? >> 8 ) | ( 0x80 | ( $? & 0x7F ) ) );